#include <string.h>
#include <math.h>
#include <allegro.h>
#include <stdio.h>

#include "include/global.h"
#include "include/logger.h"
#include "include/display.h"
#include "include/terrain.h"

typedef struct 
{
	char a;
	char b;
	char c;
} __attribute__ ((__packed__)) threebytes;

void free_terrain(TERRAIN *terr)  
{
	if(terr != NULL)
	{
		if(terr->data != NULL)
			free(terr->data);
		free(terr);
	}
}

void draw_terrain(BITMAP *bp, TERRAIN *terr, BITMAP *texture, int offset)
{
	uintptr_t address; 
	for(int J = 0; J < terr->h; J++)
	{ 
		address = bmp_write_line(bp, J);
		for(int I = 0; I < terr->w; I++)
		{
			unsigned char d = terr->data[terr->w*J+I]; 
			if(d != 0)
			{ 
				if(d & 1 << 7)
				{
					switch(SC_DEPTH)
					{
					case 32:
						bmp_write32(	address+I*4, 
							((long *)texture->line[0])[0]);
						amazolog("eat shorts\n");
						break;
					case 16:
						bmp_write16(	address+I*2,
							((short *)texture->line[0])[0]);
						break;
					}
				}
				else {
				switch(SC_DEPTH)
			 	{  
				case 32:
				{ 
					bmp_write32(	address+I*4, 
						((long *)texture->line[J % 255])[I % 255]);
					break;
				} 
				case 24: 
				{	
					/// This shit dont work right yet
					bmp_write24(	address+I*4, 
						((long *)texture->line[J % 255])[I % 255]);
					break;
				}
				case 15:
				case 16:
				{	bmp_write16(	address+I*2, 
						((short *)texture->line[J % 255])[I % 255]);
					break;
				}
				default:
					// don't use this yet
					bmp_write8(address+I, texture->line[J % 255][I % 255]);
					break;
				}	
				}		
			}
		}
	}
	//getpixel(texture, I % 255, J % 255)
}

/*
 * Function: generate_terrain
 *
 * Data ptr should point to a place in memory where 2 + w * h bytes are 
 * allocated
 *
 * Returns 1 on success
 */
TERRAIN * generate_terrain(int w, int h, int ttop)
{
	TERRAIN * result = malloc(sizeof(int)*2 + sizeof(unsigned char*));
	result->w = w;
	result->h = h;
	
	// Clear the data memory
	result->data = malloc(w*h);	// each cell = 1 byte
	
	memset(result->data, 0, w*h);
	
	// Place the main line
	for(int I = 0; I < w; I++)
		result->data[ttop*w+I] = 1;
	result->data[ttop*w] = (result->data[(ttop+1)*w] = 1);
	
	// Fill the holes from right-bottom up
	for(int I = w-1; I >= 0; I--) {		// x
		for(int J = h-1; J >= 0; J--) {	// y
			if(result->data[J*w+I] == 1) 
				break;
			else 
				result->data[J*w+I] = 1;
		}
	}
	return result;
}
